package com.ruoyi.livesass.api.sync;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cyl.manager.act.domain.entity.CouponActivity;
import com.cyl.manager.act.mapper.CouponActivityMapper;
import com.cyl.manager.act.service.CouponActivityNewService;
import com.cyl.manager.ums.domain.entity.Member;
import com.cyl.manager.ums.mapper.MemberMapper;
import com.google.common.collect.Maps;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.livesass.LiveVideoService;
import com.ruoyi.livesass.api.domain.LbsGkscDay;
import com.ruoyi.livesass.api.mapper.LbsGkscDayMapper;
import com.ruoyi.livesass.api.service.LbsGkscDayService;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.impl.SysDeptServiceImpl;
import com.volcengine.model.livesaas.response.GetUserBehaviorListResponseAPIV2;
import com.volcengine.model.livesaas.response.GetUserBehaviorListResponseAPIV2.UserBehaviorV2;
import com.volcengine.model.livesaas.response.ListActivityAPIResponse;
import com.volcengine.model.livesaas.response.ListActivityAPIResponse.ListActivityAPIForm;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;

/**
 * @ClassName: LiveUserTimeDataToDaySynService
 * @Description: TODO(直播用户观看时长-每日入库)
 * @author 晏大兵
 * @date 2025年2月10日 上午11:13:23
 */
@Component("gkscDaySynGssj")
@Order(3)
public class LiveUserTimeDataToDaySynServiceGssj  {

	private static final Logger LOG = LoggerFactory.getLogger(LiveUserTimeDataToDaySynServiceGssj.class);

	@Autowired
	LiveVideoService liveVideoService;

	@Autowired
	LbsGkscDayMapper lbsGkscDayMapper;

	@Autowired
	LbsGkscDayService lbsGkscDayService;

	@Autowired
	MemberMapper memberMapper;

	@Autowired
	private RedisCache redisCache;

	@Autowired
	private ISysConfigService configService;
	
	@Autowired
	SysDeptServiceImpl sysDeptServiceImpl;
	
	@Autowired
	CouponActivityMapper couponActivityMapper;
	
	@Autowired
	CouponActivityNewService couponActivityNewService;
	
	Map<String, JSONObject> repeatSubUserName = Maps.newHashMap();
	
	

	// 这里用于每日凌晨跑一次遗漏数据
	//@Scheduled(cron = "${custom.synTasks.liveUserTimeToDayTask}")
	public void performTask(Integer kssj, Integer jssj) throws Exception {
		

		String kssjStr = DateTime.of(""+kssj, "yyyyMMdd").toDateStr();
		String jssjStr = DateTime.of(""+jssj, "yyyyMMdd").toDateStr();
		
		try {
			
			
			LOG.error("根据开始时间["+ kssjStr +"]结束时间["+ jssjStr +"]日入库开始");
			
			
			this.syncLoadSysConfig (kssjStr, jssjStr);
			
		} catch (Exception e) {
			e.printStackTrace();
			LOG.error("定时任务异常 | 重新执行");
		}

		LOG.error("根据开始时间["+ kssjStr +"]结束时间["+ jssjStr +"]日入库结束 ：" + System.currentTimeMillis());
	}

	
	
	
	public void syncLoadSysConfig(String kssj, String jssj) throws Exception {
		SysConfig sysConfig = configService.selectConfigByKey2("sys_config");
		if (null != sysConfig && !StrUtil.isBlankIfStr(sysConfig.getRemark())) {
			JSONObject sysConfigJsonObject = JSONObject.parseObject(sysConfig.getRemark());
			if (sysConfigJsonObject.containsKey("activityConfig")) {
				JSONArray activityConfigList = sysConfigJsonObject.getJSONArray("activityConfig");
				
				for (int i = 0; i < activityConfigList.size(); i++) { //去重subusername
					JSONObject item = activityConfigList.getJSONObject(i);
					repeatSubUserName.put(item.getString("subusername"), item);
				}
				
				for(String sunName : repeatSubUserName.keySet()) {
					this.syncLiveUserTimeDataToDay(sunName, kssj, jssj);
				}
				
				/*
				for (int i = 0; i < activityConfigList.size(); i++) {
					JSONObject item = activityConfigList.getJSONObject(i);
					this.syncLiveUserTimeDataToDay(item.getString("subusername"), kssj, jssj);
				}*/
			}
		}
	}

	/**
	 * @Title: syncLiveVideoFlows
	 * @Description: TODO(同步直播流量数据)
	 * @param 设定文件
	 * @return void 返回类型
	 * @throws Exception
	 * @throws
	 */
	public void syncLiveUserTimeDataToDay(String userName, String kssj, String jssj) throws Exception {

		//首先查询出需要统计的直播间
		DateTime nowDayTime = DateTime.of(kssj, "yyyy-MM-dd");
		int pageNo = 1;
		int pageItemCount = 10000;
		int status = 0; // 已结束的直播间
		String sortBy = "LiveTime";
		String sortOrder = "Desc";

		// 更新当天时长数据
		long toDayTime = (nowDayTime.toJdkDate().getTime() / 1000);
		
		
		ListActivityAPIResponse listActivityAPIResponse = liveVideoService.listActivity(pageNo, pageItemCount,
				userName, status, sortBy, sortOrder, toDayTime);
		List<ListActivityAPIForm> listActivity = listActivityAPIResponse.getResult().getActivities();
		
		LOG.error("所需同步的直播间subname["+userName+"]liveTime["+toDayTime+"] | 直播间数量["+ listActivity.size() +"]" );
		
		processToDay(listActivity, kssj, jssj);
	}

	/**
	 * @Title: processOffsetDay
	 * @Description: TODO(根据返回的直播间进行循环查询合并观看时长)
	 * @param @param offsetMonthListActivity 设定文件
	 * @return void 返回类型
	 * @throws Exception
	 * @throws
	 */
	private void processToDay(List<ListActivityAPIForm> offsetMonthListActivity, String kssj, String jssj) throws Exception {
		Date dayDateEnd = DateTime.of(jssj, "yyyy-MM-dd");
		long jssjTime = DateUtil.endOfDay(dayDateEnd).toJdkDate().getTime();
		
		for (ListActivityAPIForm item : offsetMonthListActivity) {
			long zbkssj = item.getLiveTime() * 1000;
			String gsrq = DateTime.of( zbkssj ).toDateStr();
			
			
			Map<String, LbsGkscDay> userGkscMap = Maps.newHashMap();
			
			long activityId = item.getId();
			long pageNo = 1;
			long pageCount = 500;
			int gksc = 0;
			long scqId = 0;
			
			CouponActivity couponActivity = new CouponActivity();
			couponActivity.setZbjlid(activityId);
			couponActivity.setQlx(2); //时长券
			
			List<CouponActivity> couponActivityList = couponActivityMapper.selectByEntity(couponActivity);
			if(null != couponActivityList && couponActivityList.size() > 0 ) {
				gksc = couponActivityList.get(0).getGksc();
				scqId = couponActivityList.get(0).getId();
			}
			
			//activityId
			
			
			GetUserBehaviorListResponseAPIV2 apiResponse = liveVideoService.getUserBehaviorDataList(activityId, pageNo, pageCount);
			List<UserBehaviorV2> userList = apiResponse.getResult().getData();

			if(null == userList || userList.size() == 0) {
				continue ;
			}
			
			if(zbkssj > jssjTime) {
				continue ;
			}
			
			LOG.error("直播间名称["+item.getName()+"],ID["+item.getId()+"]，同步的用户[" + userList.size() + "],开播时间["+item.getLiveTime()+"],开播时间["+gsrq+"],观看时长["+gksc+"]");
			
			processUserLiveTime(userList, userGkscMap, gsrq, item);

			if (apiResponse.getResult().getTotalItemCount() > (pageNo * pageCount)) {// 代表一页取完数据
				long countItemSize = apiResponse.getResult().getTotalItemCount();
				long pageSize = (long) Math.ceil((double) countItemSize / pageCount);
				for (int i = 1; i < pageSize; i++) {
					pageNo++;
					
					long startTime = System.currentTimeMillis();
					
					try {
						apiResponse = liveVideoService.getUserBehaviorDataList(activityId, pageNo, pageCount);
						
					}catch(Exception e) {
						e.printStackTrace();
						System.out.println("获取直播时长分页查询错误zbjid[" + activityId + "], pageNo[" + pageNo + "] ,错误信息: " + e.getMessage());
						apiResponse = liveVideoService.getUserBehaviorDataList(activityId, pageNo, pageCount);
					}
					
					
					userList = apiResponse.getResult().getData();
					
					if(null == userList || userList.size() == 0) { //如果分页查询异常，这里循环20次调用 每次间隔3秒
						int errorCount = 0;
						while(errorCount >= 20) {
							Thread.sleep(3000);
							try {
								apiResponse = liveVideoService.getUserBehaviorDataList(activityId, pageNo, pageCount);
								userList = apiResponse.getResult().getData();
								if(null != userList && userList.size() != 0) {
									break ;
								}
							}catch(Exception e) {
								LOG.error("循环同步观看时长异常" + e.getMessage());
								e.printStackTrace();
							}finally {
								errorCount++;
							}
						}
					}
					
					long endTime = System.currentTimeMillis();
					
					LOG.error("同步的直播间 耗时["+(endTime-startTime)+"] pageNo["+pageNo+"], pageSize["+pageSize+"], pageCount["+pageCount+"]");
					
					processUserLiveTime(userList, userGkscMap, gsrq, item);
				}
			}
			
			int insertCount = 0;
			
			// 数据入库
			for (String key : userGkscMap.keySet()) {
				LbsGkscDay lbsGkscDayItem = userGkscMap.get(key);

				if (null != lbsGkscDayItem.getId() && lbsGkscDayItem.getId() != 0) {
					lbsGkscDayService.update(lbsGkscDayItem);
				} else {
					lbsGkscDayService.insert(lbsGkscDayItem);
				}
				
				//完成后判断是否需要调用观看时长补发
				if(gksc != 0 && lbsGkscDayItem.getLivetime() >= gksc) {
					try {
						couponActivityNewService.receiveCouponScqBf(scqId, lbsGkscDayItem.getWcUserId());
					}catch (Exception e) {
						LOG.error("补发券异常 scqId["+scqId+"], WcUserId["+lbsGkscDayItem.getWcUserId()+"]");
						e.printStackTrace();
					}
				}
				
				insertCount++;
				if(insertCount % 200 == 0) {
					LOG.error("开始同步按天统计用户观看时长-数据入库 count["+insertCount+"]");
				}
			}
		}

		
	}

	private void processUserLiveTime(List<UserBehaviorV2> userList, Map<String, LbsGkscDay> userGkscMap, String gsrq, ListActivityAPIForm item) {

		
		if(null == userList || userList.size() == 0) {
			return ;
		}
		
		
		for (UserBehaviorV2 userBehaviorItem : userList) {
			String userIdStr = userBehaviorItem.getExternalUserId();

			//LOG.error("同步的用户ExternalUserId[" + userIdStr + "],WatchTime["+ userBehaviorItem.getWatchTime() +"]");
			
			if (null == userIdStr || "".equals(userIdStr)) {
				continue;
			}

			LbsGkscDay lbsGkscday = null;
			if (userGkscMap.containsKey(userIdStr)) {
				lbsGkscday = userGkscMap.get(userIdStr);
			} else {
				long wcUserId = Long.valueOf(userIdStr);
				Member member = memberMapper.selectById(wcUserId);
				if (null == member) { // 没有找到对应的会员
					continue;
				}
				lbsGkscday = initLbsGkscDay(member, wcUserId, gsrq, item);
				lbsGkscday.setLivetime(0);
				
				//ThumbUpNumber 点赞次数
				//CommentCounts 发送弹幕次数
				//UserName 火山观众昵称
				//UserId 火山观众ID
				userGkscMap.put(userIdStr, lbsGkscday);
			}

			
			//TODO 这里取消累加
			/*
			Integer reLiveTime = lbsGkscday.getLivetime();
d
			if (null == reLiveTime) {
				reLiveTime = new Integer(0);
			}
			Long sumTime = (reLiveTime + userBehaviorItem.getWatchTime());
			lbsGkscday.setLivetime(sumTime.intValue());*/
			lbsGkscday.setHsUserId(userBehaviorItem.getUserId());
			lbsGkscday.setHsUserName(userBehaviorItem.getUserName());
			lbsGkscday.setDzsl(userBehaviorItem.getThumbUpNumber());
			lbsGkscday.setDmsl(userBehaviorItem.getCommentCounts());
			lbsGkscday.setAccessTime(userBehaviorItem.getAccessTime());
			String userDevices = StringUtils.join(userBehaviorItem.getUserDevice(), ",");
			lbsGkscday.setUserDevice(userDevices);
			
			String jrsj = StringUtils.join(userBehaviorItem.getJoinAt(), ",");
			lbsGkscday.setJrsj(jrsj);
			
			String lksj = StringUtils.join(userBehaviorItem.getLeaveAt(), ",");
			lbsGkscday.setLksj(lksj);
			
			
			//TODO 这里火山有bug 使用 viewDuration
			//lbsGkscday.setLivetime(userBehaviorItem.getWatchTime().intValue());
			
			Long viewDuration = (userBehaviorItem.getViewDuration() / 60);
			lbsGkscday.setLivetime(viewDuration.intValue());
			
			

		}

	}

	private LbsGkscDay initLbsGkscDay(Member member, long wcUserId, String gsrq, ListActivityAPIForm item) {
		long zbjid = item.getId();
		String zbjmc = item.getName();
		QueryWrapper<LbsGkscDay> qw = new QueryWrapper();
		qw.eq("wc_user_id", wcUserId);
		qw.eq("gsrq", gsrq);
		qw.eq("zbjid", zbjid);

		LbsGkscDay lbsGkscday = lbsGkscDayMapper.selectOne(qw);
		if (null == lbsGkscday) {
			lbsGkscday = new LbsGkscDay();
			lbsGkscday.setGsrq(gsrq);
		}

		lbsGkscday.setZbjid(zbjid);
		lbsGkscday.setZbjmc(zbjmc);
		lbsGkscday.setDeptTzId(member.getDeptTzId());
		lbsGkscday.setDeptZbjId(member.getDeptZbjId());
		lbsGkscday.setDeptDpId(member.getDeptDpId());
		lbsGkscday.setSpreaduid(member.getSpreaduid());
		
		SysDept sysDept = sysDeptServiceImpl.getCacheSysDept(member.getDeptDpId());
		if(null != sysDept) {
			lbsGkscday.setDeptDpName(sysDept.getDeptName());
		}
		
		lbsGkscday.setWcUserId(wcUserId);
		lbsGkscday.setAvatar(member.getAvatar());
		lbsGkscday.setNickname(member.getNickname());
		return lbsGkscday;
	}

}
